二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
- 任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 任意节点的左、右子树也分别为二叉查找树;
- 没有键值相等的节点。
如下所示为一棵二叉查找树:
定义节点类
二叉树的每个节点有三个属性:
- 左节点
- 右节点
- 节点值
所以用Python定义一个节点类为:1
2
3
4
5class Node:
def __init__(self, data,left=None,right=None):
self.left = left
self.right = right
self.data = data
现在来创建一个根节点为8的树:1
root=Node(8)
如下图所示:
插入节点
比较要插入数据和根节点的大小,递归的调用插入方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Node:
...
def insert(self, data):
if self.data:#如果存在根节点
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
elif data > self.data:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
现在来插入三个节点:
1 | root.insert(3) |
现在的二叉树如下所示:
继续增加一些节点,让二叉树看起来更完整:1
2
3
4
5root.insert(6)
root.insert(4)
root.insert(7)
root.insert(14)
root.insert(13)
二叉查找树的查找
1 | class Node: |
查找是否存在节点6,并返回这个节点和其父节点:1
node, parent = root.lookup(6)
其中查找的过程如下所示:
删除节点
在删除节点时,首先得统计节点孩子的个数:
1 | class Node: |
删除节点,分三种情况:
- 要删除的节点没有孩子节点
- 要删除的节点有一个孩子节点
- 要删除的节点有两个孩子节点
1 | class Node: |
打印二叉树
按照中序打印二叉树,前序和后序只需要修改打印的顺序就行。1
2
3
4
5
6
7
8
9
10
11class Node:
...
def print_tree(self):
"""
Print tree content inorder
"""
if self.left:
self.left.print_tree()
print self.data,
if self.right:
self.right.print_tree()
按层次打印一个树:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Node:
...
def print_each_level(self):
# Start off with root node
thislevel = [self]
# While there is another level
while thislevel:
nextlevel = list()
#Print all the nodes in the current level, and store the next level in a list
for node in thislevel:
print node.data
if node.left: nextlevel.append(node.left)
if node.right: nextlevel.append(node.right)
print
thislevel = nextlevel
比较两棵树
1 | class Node: |
二叉树的重建
根据前序遍历和中序遍历来重建树,重建的原理可以参看这篇博文根据二叉树的前序和中序求后序:1
2
3
4
5
6
7
8def rebuilt(preorder,inorder):
if preorder=='' or inorder=='':
return None
root=preorder[0]
index=inorder.index(root)
return Node(root,
rebuilt(preorder[1:1+index],inorder[0:index]),
rebuilt(preorder[index+1:],inorder[index+1:]))
根据中序和后序来重建树:
1 | def rebuilt1(inorder,postorder): |